<template>
	<view class="goods-sku" catchtouchmove="true" :class="showSkuPopup && complete ? 'show' : 'hide'"
		@touchmove.stop.prevent="moveHandle" @click.stop="stop">
		<!-- 遮罩层 -->
		<view class="mask" @click="close('mask')"></view>
		<!-- 主体层 -->
		<view class="layer">
			<!-- 主体 -->
			<scroll-view scroll-y="true">
				<!-- 图片，价格，库存 -->
				<view class="sku-body">
					<view class="goods-image">
						<image style="width: 100%;height: 100%;"
							:src="selectShop.image ? selectShop.image : goodsInfo[goodsThumbName]" mode="aspectFit"
							@click="previewImage()">
						</image>
					</view>
					<view class="flex flex-column px-1">
						<view class="py-1">
							<view class="goods-price">{{ priceCom | Money }}</view>
						</view>
						<view class="px-1">
							<view>{{ '剩余: ' + stockCom + ' 件'}}</view>
						</view>
					</view>
				</view>
				<!-- sku规格 -->
				<view class="sku-spec" v-show="isManyCom" v-for="(item1, index1) in goodsInfo[specListName]"
					:key="index1">
					<view class="p-1">
						<view class="px-1">{{ item1.name }}</view>
					</view>
					<view class="sku-spec-flex px-1">
						<view class="spec-name" v-for="(item2, index2) in item1.list" :key="index2"
							:class="[item2.ishow ? '' : 'noactived', subIndex[index1] == index2 ? 'actived' : '']"
							@click="skuClick(item2, index1, index2)">
							{{ item2.name }}
						</view>
					</view>
				</view>
				<!-- 数量 -->
				<view class="p-1">
					<view class="p-1">数量</view>
					<view class="px-1">
						<number-box v-model="selectNum" :min="minBuyNum || 1" :max="maxBuyNumCom" color="#F7441D"
							:positive-integer="true" :disabled="disabledMP" :disabledInput="true">
						</number-box>
					</view>
				</view>
			</scroll-view>
			<!-- 计数 -->
			<sku-button :mode="mode" :outFoStock="outFoStock" @buy="buyNow()" @cart="addCart()"></sku-button>
		</view>
	</view>
</template>

<script>
	import Constants from '@/constants';
	import NumberBox from './number-box';
	import SkuButton from './sku-button';
	/**
	 * GoodsSkuPopup
	 * @description 该组件一般用于商城购物选择物品数量的场景
	 * @property {showSkuPopup} 是否显示 true显示，false不显示
	 * @property {localData} 本地数据源，外部传入需按照指定规则来设置
	 * @property {mode} 按钮显示模式，1:都显示 2:只显示购物车 3:只显示立即购买 4:显示缺货按钮
	 * @property {goodsIdName} 商品字段id名称，对应localData中字段名称
	 * @property {skuIdName} sku字段id名称，对应localData中字段名称
	 * @property {skuListName} sku集合字段名称，对应localData中字段名称
	 * @property {specListName} spec集合字段名称，对应localData中字段名称
	 * @property {skuArrName} sku名称字段名称，对应localData中字段名称
	 * @property {defaultSingleSkuName} 默认sku字段名称
	 * @property {stockName} 库存字段名称，对应localData中字段名称
	 * @property {goodsThumbName} 商品缩略图字段名称，对应localData中字段名称
	 * @property {maskCloseAble} 是否点击遮罩层关闭，默认是
	 * @event {Function} open 打开后处理动作
	 * @event {Function} close 关闭后处理动作，如参数是mask则为背景关闭，close则为按钮关闭
	 * @event {Function} buy-now 立即购买
	 * @example <goods-sku-popup :showSkuPopup.sync="showSkuPopup" :localData="goodsInfo" :mode="skuMode" :maskCloseAble="true" @buy-now="buyNow()" />
	 */
	export default {
		//
		name: 'skuPopup',
		mixins: [Constants],
		//
		components: {
			NumberBox,
			SkuButton
		},
		//
		props: {
			//是否显示商品sku弹出层 
			showSkuPopup: {
				Type: Boolean,
				default: false
			},
			localData: {
				type: Object
			},
			mode: {
				Type: Number,
				default: 1
			},
			goodsIdName: {
				Type: String,
				default: '_id'
			},
			skuIdName: {
				Type: String,
				default: '_id'
			},
			skuListName: {
				Type: String,
				default: 'sku_list'
			},
			specListName: {
				Type: String,
				default: 'spec_list'
			},
			skuArrName: {
				Type: String,
				default: 'sku_name_arr'
			},
			defaultSingleSkuName: {
				Type: String,
				default: '默认'
			},
			stockName: {
				Type: String,
				default: 'stock'
			},
			goodsThumbName: {
				Type: [String],
				default: 'goods_thumb'
			},
			//是否阴影关闭
			maskCloseAble: {
				Type: Boolean,
				default: true
			},
			//最小购买数量 默认 1
			minBuyNum: {
				Type: [Number, String],
				default: 1
			},
			//最大购买数量 默认 100000
			maxBuyNum: {
				Type: [Number, String],
				default: 100000
			},
			//步进器步长 默认 1
			// stepBuyNum: {
			// 	Type: [Number, String],
			// 	default: 1
			// },
			//是否只能输入 step 的倍数
			// stepStrictly: {
			// 	Type: Boolean,
			// 	default: false
			// },
			/**
			 * 金额是否需要除以100
			 * 1:金额会除以100
			 * 0:金额不会除以100
			 */
			amountType: {
				Type: Number,
				default: 0
			},
			//每次选择完SKU后，购买数量归1，如果有最小购买数量，则设置为最小购买数量
			selectedInit: {
				Type: Boolean,
				default: false
			}
		},
		//
		data() {
			return {
				//组件是否加载完成
				complete: false,
				//商品信息
				goodsInfo: {},
				//是否已初始化
				initKey: true,
				//存放要和选中的值进行匹配的数据,sku集合
				shopItemInfo: {},
				//被选中的值
				selectArr: [],
				//是否选中 因为不确定是多规格还是单规格，所以这里定义数组来判断
				subIndex: [],
				//存放最后选中的商品
				selectShop: {},
				//选中数量
				selectNum: this.minBuyNum || 1,
				//是否全部sku都缺货
				outFoStock: false,
				//是否可以点击+ -
				disabledMP: true
			};
		},
		//
		computed: {
			//最大购买数量
			maxBuyNumCom() {
				let that = this;
				let max = that.maxBuyNum || 100000;
				let stockName = that.stockName;
				if (that.selectShop && typeof that.selectShop[stockName] !== 'undefined') {
					// 最大购买量不能超过当前商品的库存
					if (max > (that.selectShop[stockName] - that.selectShop.freezeStock)) {
						max = that.selectShop[stockName]- that.selectShop.freezeStock;
					}
				}
				return max;
			},
			//是否是多规格
			isManyCom() {
				let that = this;
				let {
					goodsInfo,
					defaultSingleSkuName,
					specListName
				} = that;
				let isMany = true;
				if (
					goodsInfo[specListName] &&
					goodsInfo[specListName].length === 1 &&
					goodsInfo[specListName][0].list.length === 1 &&
					goodsInfo[specListName][0].name === defaultSingleSkuName
				) {
					isMany = false;
				}
				return isMany;
			},
			//价格区间计算
			priceCom() {
				let str = '';
				let that = this;
				let {
					selectShop = {}, goodsInfo = {}, skuListName, skuIdName
				} = that;
				if (selectShop[skuIdName]) {
					str = that._priceFilter(selectShop.price);
				} else {
					let skuList = goodsInfo[skuListName];
					if (skuList && skuList.length > 0) {
						let valueArr = [];
						skuList.map((skuItem, index) => {
							valueArr.push(skuItem.price);
						});
						let min = that._priceFilter(Math.min(...valueArr));
						let max = that._priceFilter(Math.max(...valueArr));
						if (min === max) {
							str = min + '';
						} else {
							str = `${min} - ${max}`;
						}
					}
				}
				return str;
			},
			//库存区间计算
			stockCom() {
				let str = '';
				let that = this;
				let {
					selectShop = {}, goodsInfo = {}, skuListName, stockName
				} = that;
				if (selectShop[stockName]) {
					str = selectShop[stockName];
					if(selectShop.freezeStock){
						str = selectShop[stockName] - selectShop.freezeStock;
					}
				} else {
					let skuList = goodsInfo[skuListName];
					if (skuList && skuList.length > 0) {
						let valueArr = [];
						skuList.map((skuItem, index) => {
							valueArr.push(skuItem[stockName] || 0);
						});
						let min = Math.min(...valueArr);
						let max = Math.max(...valueArr);
						if (min === max) {
							str = min;
						} else {
							str = `${min} - ${max}`;
						}
					}
				}
				if (str) {
					that.disabledMP = false;
				}
				return str;
			}
		},
		//
		watch: {
			//监听是否显示弹出层
			showSkuPopup(newVal, oldValue) {
				let that = this;
				if (newVal) {
					that.open();
				}
			}
		},
		//
		methods: {
			//关闭
			close(s) {
				let that = this;
				if (s === 'mask') {
					if (that.maskCloseAble !== false) {
						that.$emit('update:showSkuPopup', false);
						// that.$emit('close', 'mask');
					}
				} else {
					that.$emit('update:showSkuPopup', false);
					// that.$emit('close', 'close');
				}
			},
			//打开
			async open() {
				let that = this;
				let goodsInfo = that.localData;
				if (goodsInfo && typeof goodsInfo == 'object' && JSON.stringify(goodsInfo) != '{}') {
					let that = this;
					let {
						skuListName
					} = that;
					//
					if (JSON.stringify(that.goodsInfo) === '{}' || that.goodsInfo[that.goodsIdName] !== goodsInfo[that
							.goodsIdName]) {
						that.goodsInfo = goodsInfo;
						that.initKey = true;
					} else {
						that.goodsInfo[skuListName] = goodsInfo[skuListName];
					}
					//
					if (that.initKey) {
						that.initKey = false;
						//初始化基础参数值
						that.init(that.isManyCom);
					}
					//更新选中sku的库存信息
					let select_sku_info = that._getListItem(that.goodsInfo[skuListName], that.skuIdName, that
						.selectShop[that.skuIdName] ? that.selectShop[that.skuIdName] : []);
					Object.assign(that.selectShop, select_sku_info);
					that.complete = true;
				} else {
					that._toast('未获取到商品信息', 'none');
					that.$emit('update:showSkuPopup', false);
					return false;
				}
			},
			/**
			 * 初始化商品sku相关参数
			 * @param {Object} notAutoClick 是否自动选取sku
			 */
			init(notAutoClick) {
				let that = this;
				//被选中的值（sku属性）
				that.selectArr = [];
				//被选中的值（sku属性下标）
				that.subIndex = [];
				//最后选中的商品
				that.selectShop = {};
				//商品数量
				that.selectNum = that.minBuyNum || 1;
				//是否全部sku都缺货
				that.outFoStock = false;
				//
				that.shopItemInfo = {};
				//
				let specListName = that.specListName;
				//
				that.goodsInfo[specListName].map(item => {
					that.selectArr.push('');
					that.subIndex.push(-1);
				});
				//计算sku里面规格形成路径
				that._checkItem();
				//传-1是为了不跳过循环
				that._checkInpath(-1);
				//自动选择sku策略
				if (!notAutoClick) that._autoSkuClick();
			},
			/**
			 * 得到被选中的sku
			 * @param {Object} list sku集合
			 * @param {Object} key 索引
			 * @param {Object} value specList.name
			 */
			_getListItem(list, key, value) {
				let that = this;
				let item;
				for (let i in list) {
					//
					if (JSON.stringify(list[i][key]) === JSON.stringify(value)) {
						item = list[i];
						break;
					}
				}
				return item;
			},
			/**
			 * 点击sku
			 * @param {Object} value 选中的sku值
			 * @param {Object} index1 规格索引
			 * @param {Object} index2 sku索引
			 */
			skuClick(value, index1, index2) {
				let that = this;
				if (value.ishow) {
					if (that.selectArr[index1] != value.name) {
						that.$set(that.selectArr, index1, value.name);
						that.$set(that.subIndex, index1, index2);
					} else {
						that.$set(that.selectArr, index1, '');
						that.$set(that.subIndex, index1, -1);
					}
					//
					that._checkInpath(index1);
					//如果全部选完
					that._checkSelectShop();
				}
			},
			/**
			 * 检查路径
			 * @param {Object} clickIndex 选中的索引值
			 */
			_checkInpath(clickIndex) {
				let that = this;
				let specListName = that.specListName;
				//循环所有属性判断哪些属性可选
				//当前选中的兄弟节点和已选中属性不需要循环
				let specList = that.goodsInfo[specListName];
				for (let i = 0, len = specList.length; i < len; i++) {
					if (i == clickIndex) {
						continue;
					}
					let len2 = specList[i].list.length;
					for (let j = 0; j < len2; j++) {
						if (that.subIndex[i] != -1 && j == that.subIndex[i]) {
							continue;
						}
						let choosed_copy = [...that.selectArr];
						that.$set(choosed_copy, i, specList[i].list[j].name);
						let choosed_copy2 = choosed_copy.filter(item => item !== '' && typeof item !== 'undefined');
						if (that.shopItemInfo.hasOwnProperty(that.getArrayToSting(choosed_copy2))) {
							specList[i].list[j].ishow = true;
						} else {
							specList[i].list[j].ishow = false;
						}
					}
				}
				that.$set(that.goodsInfo, specListName, specList);
			},
			//检测是否已经选完sku
			_checkSelectShop() {
				let that = this;
				//如果全部选完
				if (that.selectArr.every(item => item != '')) {
					that.selectShop = that.shopItemInfo[that.getArrayToSting(that.selectArr)];
					let stock = that.selectShop[that.stockName];
					if (typeof stock !== 'undefined' && that.selectNum > stock) {
						that.selectNum = stock;
					}
					if (that.selectNum > that.maxBuyNum) {
						that.selectNum = that.maxBuyNum;
					}
					if (that.selectNum < that.minBuyNum) {
						that.selectNum = that.minBuyNum;
					}
					if (that.selectedInit) {
						that.selectNum = that.minBuyNum || 1;
					}
				} else {
					that.selectShop = {};
				}
			},
			//计算sku有多少种规格形成路径
			_checkItem() {
				let that = this;
				let {
					stockName
				} = that;
				let skuListName = that.skuListName;
				//去除库存小于等于0的商品sku
				let originalSkuList = that.goodsInfo[skuListName];
				let skuList = [];
				let stockNum = 0;
				originalSkuList.map((skuItem, index) => {
					if (skuItem[stockName] > 0) {
						skuList.push(skuItem);
						stockNum += skuItem[stockName];
					}
				});
				if (stockNum <= 0) {
					that.outFoStock = true;
				}
				//计算有多小种可选路径
				let result = skuList.reduce(
					(arrs, items) => {
						return arrs.concat(
							items[that.skuArrName].reduce(
								(arr, item) => {
									// console.log('that.skuArrName: ',arr);
									// console.log('that.skuArrName: ',item);
									return arr.concat(
										arr.map(item2 => {
											// 利用对象属性的唯一性实现二维数组去重
											if (!that.shopItemInfo.hasOwnProperty(that.getArrayToSting([...
													item2, item
												]))) {
												that.shopItemInfo[that.getArrayToSting([...item2, item])] =
													items;
											}
											return [...item2, item];
										})
									);
								},
								[
									[]
								]
							)
						);
					},
					[
						[]
					]
				);
			},
			/**
			 * 只有一组sku,默认选择最前面有库存的sku
			 */
			_autoSkuClick() {
				let that = this;
				let skuList = that.goodsInfo[that.skuListName];
				let specListArr = that.goodsInfo[that.specListName];
				//sku和spec应该是一一对应的，长度等于1说明只有一个sku
				if (specListArr.length == 1) {
					//逻辑上specList应该也是一
					let specList = specListArr[0].list;
					for (let i = 0; i < specList.length; i++) {
						//判断有没有sku，如果有默认选中
						let sku = that._getListItem(skuList, that.skuArrName, [specList[i].name]);
						if (sku) {
							that.skuClick(specList[i], 0, i);
							break;
						}
					}
				}
			},
			//价格转换
			_priceFilter(n = 0) {
				let that = this;
				if (typeof n == 'string') {
					n = parseFloat(n);
				}
				if (that.amountType === 0) {
					return n.toFixed(2);
				} else {
					return (n / 100).toFixed(2);
				}
			},
			//图片预览
			previewImage() {
				let that = this;
				let {
					selectShop,
					goodsInfo,
					goodsThumbName
				} = that;
				let src = selectShop.image ? selectShop.image : goodsInfo[goodsThumbName];
				if (src) {
					uni.previewImage({
						urls: [src]
					});
				}
			},
			//立即购买
			buyNow() {
				let that = this;
				that._checkSelectComplete({
					success: function(selectShop) {
						selectShop.buy_num = that.selectNum;
						that.$emit('buy-now', selectShop);
					}
				});
			},
			//检测sku
			_checkSelectComplete(obj = {}) {
				let that = this;
				let clickTime = new Date().getTime();
				if (that.clickTime && clickTime - that.clickTime < 400) {
					return false;
				}
				that.clickTime = clickTime;
				let {
					selectShop,
					selectNum,
					stockName
				} = that;
				if (!selectShop || !selectShop[that.skuIdName]) {
					that._toast('请先选择对应规格', 'none');
					return false;
				}
				
				if (selectNum <= 0) {
					that._toast('购买数量必须>0', 'none');
					return false;
				}
				if (selectNum > (selectShop[stockName] - selectShop.freezeStock)) {
					that._toast('库存不足', 'none');
					return false;
				}
				if (typeof obj.success == 'function') obj.success(selectShop);
			},
			//弹窗提示
			_toast(title, icon) {
				uni.showToast({
					title: title,
					icon: icon
				});
			},
			//数组转字符串
			getArrayToSting(arr) {
				let str = '';
				arr.map((item, index) => {
					item = item.replace(/\./g, '。');
					if (index == 0) {
						str += item;
					} else {
						str += ',' + item;
					}
				});
				return str;
			},
			//添加购物车
			addCart() {},
			//用于阻止冒泡
			stop() {},
			//禁止父元素滑动
			moveHandle() {}
		}
	};
</script>

<style lang="scss" scoped>
	.goods-sku {
		position: fixed;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		z-index: 100;
		overflow: hidden;
		font-size: $uni-font-size-base;
		color: $uni-text-color-regular;

		.mask {
			position: fixed;
			left: 0;
			right: 0;
			top: 0;
			height: 100%;
			width: 100%;
			z-index: 1;
			background-color: rgba(0, 0, 0, 0.4);
		}

		.layer {
			display: flex;
			flex-direction: column;
			position: fixed;
			left: 0;
			right: 0;
			bottom: 0;
			z-index: 99;
			border-radius: 10rpx 10rpx 0 0;
			background-color: $uni-bg-color;
			width: 100%;
			// 设置ios刘海屏底部横线安全区域
			// padding-bottom: constant(safe-area-inset-bottom);
			// padding-bottom: env(safe-area-inset-bottom);
		}

		.sku-body {
			display: flex;
			flex-direction: row;
			padding: 28rpx 0rpx;

			.goods-image {
				position: relative;
				width: 120rpx;
				height: 120rpx;
				background: $uni-bg-color;
				margin: $xj-standard-margin;
				overflow: hidden;
			}

			.goods-price {
				display: flex;
				justify-content: space-between;
				font-size: $uni-font-size-lg;
				color: $uni-color-price;
			}
		}

		.sku-spec {
			max-height: 350rpx;
			overflow: auto;
			.sku-spec-flex{
				display: flex;
				flex-wrap: wrap;
			}
			.spec-name {
				border-radius: 8rpx;
				padding: 0rpx 24rpx;
				margin: $uni-margin-base;
				border: 1px solid $uni-text-color-grey;
			}

			//
			.actived {
				color: #fe560a;
				border: 1px solid #fe560a;
			}

			//
			.noactived {
				color: #c8c9cc;
				background: #f2f3f5;
				border: 1px solid $uni-text-color-grey;
				// border-color: #f2f3f5;
			}
		}

		&.show {
			display: block;

			.mask {
				animation: showPopup 0.2s linear both;
			}

			.layer {
				animation: showLayer 0.2s linear both;
			}
		}

		&.hide {
			.mask {
				animation: hidePopup 0.2s linear both;
			}

			.layer {
				animation: hideLayer 0.2s linear both;
			}
		}

		&.none {
			display: none;
		}

		@keyframes showPopup {
			0% {
				opacity: 0;
			}

			100% {
				opacity: 1;
			}
		}

		@keyframes hidePopup {
			0% {
				opacity: 1;
			}

			100% {
				opacity: 0;
			}
		}

		@keyframes showLayer {
			0% {
				transform: translateY(120%);
			}

			100% {
				transform: translateY(0%);
			}
		}

		@keyframes hideLayer {
			0% {
				transform: translateY(0);
			}

			50% {
				transform: translateY(60%);
			}

			100% {
				transform: translateY(120%);
			}
		}
	}
</style>